#asset_route.py
import os
import json
from datetime import datetime
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, send_file
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename
from flask_cors import cross_origin

from inc.models import db, Asset, AssetCategory, AssetSupplier, AssetMaintenanceLog, AssetAttachment, AssetCustomField, \
    AssetAttribute, AssetAgentConfig, AssetOperationLog, AdminMember, AdminUser
from member.jira.attachment_routes import upload_file
from .asset_services import AssetService, AssetImportExportService, AssetBindingService

# 创建蓝图
asset_bp = Blueprint('asset', __name__, url_prefix='/asset')

# 配置文件上传
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'xlsx', 'xls', 'doc', 'docx'}
UPLOAD_FOLDER = 'uploads/assets'


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


def get_common_data():
    """获取公共数据"""
    return {
        'categories': AssetCategory.query.filter_by(is_active=True).all(),
        'suppliers': AssetSupplier.query.filter_by(is_active=True).all(),
        'members': AdminMember.query.filter_by(status=True).all()
    }


# ===== 页面路由 =====

# 资产列表和搜索
@asset_bp.route('/assets')
@login_required
def asset_list():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)

    filters = {
        'keyword': request.args.get('keyword', ''),
        'category_id': request.args.get('category_id', type=int),
        'status': request.args.get('status', ''),
        'confirmation_status': request.args.get('confirmation_status', ''),
        'assigned_to_id': request.args.get('assigned_to_id', type=int),
        'auto_discovered': request.args.get('auto_discovered', type=int)
    }

    success, message, pagination = AssetService.get_assets_with_filters(filters, page=page, per_page=per_page)

    stats = AssetService.get_asset_statistics()

    common_data = get_common_data()
    return render_template('admin/asset/asset_list.html',
                           assets=pagination.items,
                           pagination=pagination,
                           filters=filters,
                           stats=stats,
                           **common_data)


# 资产详情
@asset_bp.route('/assets/<int:asset_id>')
@login_required
def asset_detail(asset_id):
    asset = Asset.query.options(
        db.joinedload(Asset.category),
        db.joinedload(Asset.assigned_to),
        db.joinedload(Asset.suppliers),
        db.joinedload(Asset.maintenance_logs).joinedload(AssetMaintenanceLog.performed_by),
        db.joinedload(Asset.attachments),
        db.joinedload(Asset.attributes).joinedload(AssetAttribute.field),
        db.joinedload(Asset.created_by),
        db.joinedload(Asset.confirmed_by)
    ).get_or_404(asset_id)

    maintenance_logs = AssetMaintenanceLog.query.filter_by(asset_id=asset_id) \
        .order_by(AssetMaintenanceLog.maintenance_date.desc()).all()

    operation_logs = AssetOperationLog.query.filter_by(asset_id=asset_id) \
        .order_by(AssetOperationLog.created_at.desc()).limit(50).all()

    common_data = get_common_data()
    return render_template('admin/asset/asset_detail.html',
                           asset=asset,
                           maintenance_logs=maintenance_logs,
                           operation_logs=operation_logs,
                           **common_data)


# 添加/编辑资产
@asset_bp.route('/assets/form', methods=['GET', 'POST'])
@asset_bp.route('/assets/<int:asset_id>/form', methods=['GET', 'POST'])
@login_required
def asset_form(asset_id=None):
    asset = Asset.query.get(asset_id) if asset_id else None

    # 检查是否有保存的表单数据（来自错误重定向）
    saved_form_data = request.args.get('form_data')
    if saved_form_data:
        try:
            form_data = json.loads(saved_form_data)
        except:
            form_data = {}
    else:
        form_data = {}

    if request.method == 'POST':
        # 收集表单数据
        asset_data = {
            'name': request.form.get('name'),
            'asset_number': request.form.get('asset_number'),
            'category_id': request.form.get('category_id'),
            'model': request.form.get('model'),
            'brand': request.form.get('brand'),
            'serial_number': request.form.get('serial_number'),
            'purchase_price': request.form.get('purchase_price'),
            'purchase_date': request.form.get('purchase_date'),
            'warranty_months': request.form.get('warranty_months'),
            'depreciation_rate': request.form.get('depreciation_rate'),
            'assigned_to_id': request.form.get('assigned_to_id'),
            'location': request.form.get('location'),
            'status': request.form.get('status'),
            'description': request.form.get('description'),
            'notes': request.form.get('notes'),
            'cpu_info': request.form.get('cpu_info'),
            'memory_info': request.form.get('memory_info'),
            'disk_info': request.form.get('disk_info'),
            'os_info': request.form.get('os_info'),
            'network_info': request.form.get('network_info'),
            'supplier_ids': request.form.getlist('supplier_ids')
        }

        # 处理自定义字段
        custom_fields = {}
        for key in request.form:
            if key.startswith('custom_field_'):
                field_id = key.replace('custom_field_', '')
                custom_fields[field_id] = request.form.get(key)

        if asset_id:
            success, message, asset = AssetService.update_asset(asset_id, asset_data, custom_fields, current_user.id)
        else:
            success, message, asset = AssetService.create_asset(asset_data, custom_fields, current_user.id)

        if success:
            flash('操作成功', 'success')
            return redirect(url_for('asset.asset_detail', asset_id=asset.id))
        else:
            # 使用URL参数传递表单数据，避免页面刷新丢失
            form_data_to_save = {
                **asset_data,
                'custom_fields': custom_fields,
                'supplier_ids': request.form.getlist('supplier_ids')
            }

            # 将表单数据编码为JSON并添加到重定向URL中
            encoded_form_data = json.dumps(form_data_to_save, ensure_ascii=False)
            return redirect(url_for('asset.asset_form',
                                  asset_id=asset_id,
                                  form_data=encoded_form_data,
                                  error=message))

    common_data = get_common_data()

    # 获取自定义字段（根据当前选择的类别）
    current_category_id = None
    if form_data and 'category_id' in form_data:
        current_category_id = form_data['category_id']
    elif asset and asset.category_id:
        current_category_id = asset.category_id

    custom_fields = []
    if current_category_id:
        custom_fields = AssetCustomField.query.filter_by(
            category_id=current_category_id,
            is_active=True
        ).order_by(AssetCustomField.order_num).all()

    # 如果有错误消息，显示给用户
    error_message = request.args.get('error')
    if error_message:
        flash(error_message, 'error')

    return render_template('admin/asset/asset_form.html',
                           asset=asset,
                           form_data=form_data,  # 传递表单数据
                           custom_fields=custom_fields,
                           **common_data)


# 资产状态变更
@asset_bp.route('/assets/<int:asset_id>/status', methods=['POST'])
@login_required
def change_asset_status(asset_id):
    # 统一处理表单数据和JSON数据
    if request.is_json:
        data = request.get_json()
        new_status = data.get('status')
        notes = data.get('notes')
    else:
        # 处理表单数据
        new_status = request.form.get('status')
        notes = request.form.get('notes')

    success, message, asset = AssetService.change_asset_status(asset_id, new_status, notes, current_user.id)

    # 判断请求类型
    is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'

    if is_ajax or request.is_json:
        if success:
            return jsonify({
                'success': True,
                'message': message,
                'status': asset.status,
                'status_label': asset.status_label,
                'asset_id': asset_id
            })
        else:
            return jsonify({
                'success': False,
                'message': message,
                'asset_id': asset_id
            }), 400
    else:
        if success:
            flash('状态变更成功', 'success')
        else:
            flash(message, 'error')
        return redirect(url_for('asset.asset_detail', asset_id=asset_id))


# 资产确认操作
@asset_bp.route('/assets/<int:asset_id>/confirm', methods=['POST'])
@login_required
def confirm_asset(asset_id):
    notes = request.form.get('notes', '')

    success, message = AssetService.confirm_asset(asset_id, current_user.id, notes)

    if success:
        flash('资产确认成功', 'success')
    else:
        flash(message, 'error')

    return redirect(url_for('asset.asset_detail', asset_id=asset_id))


# 资产拒绝操作
@asset_bp.route('/assets/<int:asset_id>/reject', methods=['POST'])
@login_required
def reject_asset(asset_id):
    reason = request.form.get('reason', '')

    success, message = AssetService.reject_asset(asset_id, current_user.id, reason)

    if success:
        flash('资产已拒绝', 'success')
    else:
        flash(message, 'error')

    return redirect(url_for('asset.asset_detail', asset_id=asset_id))


# 设备绑定管理
@asset_bp.route('/assets/<int:asset_id>/bind', methods=['POST'])
@login_required
def bind_asset(asset_id):
    host_identifier = request.form.get('host_identifier')

    if not host_identifier:
        flash('请输入设备标识', 'error')
        return redirect(url_for('asset.asset_detail', asset_id=asset_id))

    success, message = AssetBindingService.bind_existing_asset(
        host_identifier, asset_id, current_user.id
    )

    if success:
        flash('绑定成功', 'success')
    else:
        flash(message, 'error')

    return redirect(url_for('asset.asset_detail', asset_id=asset_id))


@asset_bp.route('/assets/<int:asset_id>/unbind', methods=['POST'])
@login_required
def unbind_asset(asset_id):
    success, message = AssetBindingService.unbind_asset(asset_id, current_user.id)

    if success:
        flash('解绑成功', 'success')
    else:
        flash(message, 'error')

    return redirect(url_for('asset.asset_detail', asset_id=asset_id))


# 资产分配人员
@asset_bp.route('/assets/<int:asset_id>/assign', methods=['POST'])
@login_required
def assign_asset(asset_id):
    user_id = request.form.get('user_id')
    assign_date = request.form.get('assign_date')
    notes = request.form.get('notes', '')

    if not user_id:
        flash('请选择要分配的人员', 'error')
        return redirect(url_for('asset.asset_detail', asset_id=asset_id))

    success, message = AssetService.assign_asset_to_user(
        asset_id=asset_id,
        user_id=user_id,
        assign_date=assign_date,
        notes=notes,
        current_user_id=current_user.id
    )

    if success:
        flash('分配成功', 'success')
    else:
        flash(message, 'error')

    return redirect(url_for('asset.asset_detail', asset_id=asset_id))


# 自动发现资产列表
@asset_bp.route('/assets/auto-discovered')
@login_required
def auto_discovered_assets():
    page = request.args.get('page', 1, type=int)

    filters = {
        'auto_discovered': True,
        'confirmation_status': Asset.CONFIRMATION_PENDING
    }

    success, message, pagination = AssetService.get_assets_with_filters(filters, page=page)

    return render_template('admin/asset/auto_discovered.html',
                           assets=pagination.items,
                           pagination=pagination)


# 维护记录管理
@asset_bp.route('/assets/<int:asset_id>/maintenance/add', methods=['GET', 'POST'])
@login_required
def add_maintenance_log(asset_id):
    asset = Asset.query.get_or_404(asset_id)

    if request.method == 'POST':
        log_data = {
            'maintenance_type': request.form.get('maintenance_type'),
            'title': request.form.get('title'),
            'description': request.form.get('description'),
            'maintenance_date': request.form.get('maintenance_date'),
            'next_maintenance_date': request.form.get('next_maintenance_date'),
            'cost': request.form.get('cost'),
            'duration_hours': request.form.get('duration_hours'),
            'parts_replaced': request.form.getlist('parts_replaced'),
            'status': request.form.get('status', AssetMaintenanceLog.STATUS_COMPLETED),
            'performed_by_id': request.form.get('performed_by_id')
        }

        success, message, log = AssetService.create_maintenance_log(asset_id, log_data, log_data.get('performed_by_id'))

        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            if success:
                return jsonify({
                    'status': 'success',
                    'message': '维护记录添加成功'
                })
            else:
                return jsonify({
                    'status': 'error',
                    'message': message
                }), 400
        else:
            if success:
                flash('维护记录添加成功', 'success')
                return redirect(url_for('asset.asset_detail', asset_id=asset_id))
            else:
                flash(message, 'error')

    return render_template('admin/asset/maintenance_form.html', asset=asset)


# 类别管理
@asset_bp.route('/assets/categories', methods=['GET'])
@login_required
def category_list():
    categories_tree = AssetService.get_asset_categories_tree()
    return render_template('admin/asset/category_list.html', categories_tree=categories_tree)

# 创建资产类别
@asset_bp.route('/assets/categories/create', methods=['POST'])
@login_required
def create_asset_category():
    category_data = {
        'name': request.form.get('name'),
        'parent_id': request.form.get('parent_id'),
        'description': request.form.get('description'),
        'order_num': request.form.get('order_num', 0)
    }

    success, message, category = AssetService.create_asset_category(
        name=category_data['name'],
        description=category_data['description'],
        parent_id=category_data['parent_id'],
        order_num=category_data['order_num']
    )

    if success:
        flash('资产类别创建成功', 'success')
    else:
        flash(message, 'error')

    return redirect(url_for('asset.category_list'))


# 编辑资产分类
@asset_bp.route('/asset/category/<int:category_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_asset_category(category_id):
    category = AssetCategory.query.get_or_404(category_id)

    if request.method == 'POST':
        category_data = {
            'name': request.form.get('name'),
            'parent_id': request.form.get('parent_id'),
            'description': request.form.get('description'),
            'order_num': request.form.get('order_num', 0),
            'is_active': request.form.get('is_active') == 'on'
        }

        success, message = AssetService.update_asset_category(
            category_id,
            name=category_data['name'],
            description=category_data['description'],
            parent_id=category_data['parent_id'],
            order_num=category_data['order_num'],
            is_active=category_data['is_active']
        )

        if success:
            flash('资产类别更新成功', 'success')
            return redirect(url_for('asset.category_list'))
        else:
            flash(message, 'error')

    categories = AssetCategory.query.filter(
        AssetCategory.id != category_id
    ).all()

    return render_template('admin/asset/category_form.html',
                         category=category,
                         categories=categories)




# 删除资产分类
@asset_bp.route('/asset/category/delete', methods=['POST','GET'])
@login_required
def delete_asset_category():
    category_id = request.form.get('category_id')
    if not category_id:
        flash('请选择要删除的类别', 'error')
        return redirect(url_for('asset.category_list'))

    category = AssetCategory.query.get(category_id)
    if not category:
        flash('类别不存在', 'error')
        return redirect(url_for('asset.category_list'))

    # 检查是否有子类别
    has_children = AssetCategory.query.filter_by(parent_id=category_id).count() > 0
    if has_children:
        flash('该类别下有子类别，请先删除子类别', 'error')
        return redirect(url_for('asset.category_list'))

    # 检查是否有资产使用该类别
    assets_count = Asset.query.filter_by(category_id=category_id).count()
    if assets_count > 0:
        flash(f'该类别已被 {assets_count} 个资产使用，无法删除', 'error')
        return redirect(url_for('asset.category_list'))

    try:
        db.session.delete(category)
        db.session.commit()
        flash('类别删除成功', 'success')
    except Exception as e:
        db.session.rollback()
        flash(f'删除失败: {str(e)}', 'error')

    return redirect(url_for('asset.category_list'))


@asset_bp.route('/category/toggle-status', methods=['POST'])
@login_required
def toggle_category_status():
    """切换类别状态"""
    category_id = request.form.get('category_id')
    is_active = request.form.get('is_active') == 'true'

    category = AssetCategory.query.get(category_id)
    if not category:
        return jsonify({'success': False, 'message': '类别不存在'})

    try:
        category.is_active = is_active
        db.session.commit()
        return jsonify({'success': True, 'message': '状态更新成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': f'状态更新失败: {str(e)}'})

@asset_bp.route('/api/categories/<int:category_id>', methods=['GET'])
@login_required
def api_get_category(category_id):
    """获取单个类别信息的API"""
    category = AssetCategory.query.get_or_404(category_id)
    return jsonify({
        'success': True,
        'category': {
            'id': category.id,
            'name': category.name,
            'parent_id': category.parent_id,
            'description': category.description,
            'order_num': category.order_num
        }
    })


# 供应商管理
@asset_bp.route('/assets/suppliers', methods=['GET', 'POST'])
@login_required
def supplier_list():
    if request.method == 'POST':
        supplier_id = request.form.get('supplier_id')

        # 如果有supplier_id，说明是编辑操作
        if supplier_id:
            supplier = AssetSupplier.query.get(supplier_id)
            if not supplier:
                flash('供应商不存在', 'error')
                return redirect(url_for('asset.supplier_list'))

            try:
                supplier.name = request.form.get('name')
                supplier.contact_person = request.form.get('contact_person')
                supplier.contact_phone = request.form.get('contact_phone')
                supplier.contact_email = request.form.get('contact_email')
                supplier.address = request.form.get('address')
                supplier.website = request.form.get('website')
                supplier.is_active = request.form.get('is_active') == 'on'

                db.session.commit()
                flash('供应商更新成功', 'success')
            except Exception as e:
                db.session.rollback()
                flash(f'更新供应商失败: {str(e)}', 'error')
        else:
            # 新增供应商逻辑（保持不变）
            name = request.form.get('name')
            contact_person = request.form.get('contact_person')
            contact_phone = request.form.get('contact_phone')
            contact_email = request.form.get('contact_email')

            if not name:
                flash('供应商名称不能为空', 'error')
                return redirect(url_for('asset.supplier_list'))

            try:
                supplier = AssetSupplier(
                    name=name,
                    contact_person=contact_person,
                    contact_phone=contact_phone,
                    contact_email=contact_email,
                    address=request.form.get('address'),
                    website=request.form.get('website'),
                    is_active=request.form.get('is_active') == 'on'
                )
                db.session.add(supplier)
                db.session.commit()
                flash('供应商添加成功', 'success')
            except Exception as e:
                db.session.rollback()
                flash(f'添加供应商失败: {str(e)}', 'error')

        return redirect(url_for('asset.supplier_list'))

    suppliers = AssetSupplier.query.order_by(AssetSupplier.name).all()
    return render_template('admin/asset/supplier_list.html', suppliers=suppliers)



# 删除供应商
@asset_bp.route('/assets/suppliers/<int:supplier_id>/delete', methods=['POST'])
@login_required
def delete_supplier(supplier_id):
    supplier = AssetSupplier.query.get_or_404(supplier_id)

    try:
        # 检查供应商是否被资产使用
        assets_count = Asset.query.filter(Asset.suppliers.any(id=supplier_id)).count()
        if assets_count > 0:
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return jsonify({
                    'success': False,
                    'message': f'该供应商已被 {assets_count} 个资产使用，无法删除'
                }), 400
            else:
                flash(f'该供应商已被 {assets_count} 个资产使用，无法删除', 'error')
                return redirect(url_for('asset.supplier_list'))

        db.session.delete(supplier)
        db.session.commit()

        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': True,
                'message': '供应商删除成功'
            })
        else:
            flash('供应商删除成功', 'success')
    except Exception as e:
        db.session.rollback()
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': f'删除失败: {str(e)}'
            }), 500
        else:
            flash(f'删除失败: {str(e)}', 'error')

    return redirect(url_for('asset.supplier_list'))


# 切换供应商状态
@asset_bp.route('/assets/suppliers/<int:supplier_id>/toggle', methods=['POST'])
@login_required
def toggle_supplier(supplier_id):
    supplier = AssetSupplier.query.get_or_404(supplier_id)

    try:
        if request.is_json:
            data = request.get_json()
            supplier.is_active = data.get('is_active', not supplier.is_active)
        else:
            supplier.is_active = not supplier.is_active

        db.session.commit()

        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': True,
                'message': f'供应商已{"启用" if supplier.is_active else "停用"}',
                'is_active': supplier.is_active
            })
        else:
            flash(f'供应商已{"启用" if supplier.is_active else "停用"}', 'success')
    except Exception as e:
        db.session.rollback()
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': f'操作失败: {str(e)}'
            }), 500
        else:
            flash(f'操作失败: {str(e)}', 'error')

    return redirect(url_for('asset.supplier_list'))

# 统计页面
@asset_bp.route('/assets/statistics')
@login_required
def statistics():
    stats = AssetService.get_asset_statistics()
    return render_template('admin/asset/statistics.html', stats=stats)


# 导入导出
@asset_bp.route('/assets/export')
@login_required
def export_assets():
    filters = {
        'keyword': request.args.get('keyword', ''),
        'category_id': request.args.get('category_id', type=int),
        'status': request.args.get('status', ''),
        'assigned_to_id': request.args.get('assigned_to_id', type=int)
    }

    success, message, file_data = AssetImportExportService.export_assets_to_excel(filters)

    if success:
        filename = f"资产清单_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
        return send_file(file_data,
                         as_attachment=True,
                         download_name=filename,
                         mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    else:
        flash(message, 'error')
        return redirect(url_for('asset.asset_list'))


@asset_bp.route('/assets/import', methods=['GET', 'POST'])
@login_required
def import_assets():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('请选择文件', 'error')
            return redirect(request.url)

        file = request.files['file']
        if file.filename == '':
            flash('请选择文件', 'error')
            return redirect(request.url)

        if file and allowed_file(file.filename):
            update_existing = request.form.get('update_existing') == 'on'

            success, message, errors = AssetImportExportService.import_assets_from_excel(
                 file,current_user.id,update_existing
            )

            if success:
                flash(message, 'success')
                if errors:
                    flash(f"错误详情: {', '.join(errors)}", 'warning')
            else:
                flash(message, 'error')

            return redirect(url_for('asset.asset_list'))

    return render_template('admin/asset/import_assets.html')


@asset_bp.route('/assets/import/template')
@login_required
def download_import_template():
    """下载导入模板"""
    try:
        import pandas as pd
        from io import BytesIO

        # 创建模板数据
        template_data = {
            '资产编号': ['AST-2023-001', 'AST-2023-002'],
            '资产名称': ['示例笔记本电脑', '示例台式机'],
            '类别': ['笔记本电脑', '台式机'],
            '型号': ['X1 Carbon', 'OptiPlex 7080'],
            '品牌': ['联想', '戴尔'],
            '序列号': ['SN001', 'SN002'],
            '购买价格': [8999.00, 6000.00],
            '购买日期': ['2023-01-15', '2023-01-16'],
            '位置': ['A栋301室', 'B栋201室'],
            '使用人': ['张三', '李四']
        }

        df = pd.DataFrame(template_data)
        output = BytesIO()
        with pd.ExcelWriter(output, engine='openpyxl') as writer:
            df.to_excel(writer, sheet_name='资产导入模板', index=False)

        output.seek(0)
        return send_file(
            output,
            as_attachment=True,
            download_name='资产导入模板.xlsx',
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
    except Exception as e:
        flash(f'生成模板失败: {str(e)}', 'error')
        return redirect(url_for('asset.import_assets'))


# ===== API 路由 =====

@asset_bp.route('/api/assets/report', methods=['POST'])
@cross_origin()  # 添加这一行
def receive_agent_report():
    """处理Agent资产上报 - 最终修正版本"""
    try:
        return _process_agent_report()
    except Exception as e:
        logger.error(f"处理Agent上报失败: {str(e)}", exc_info=True)
        return jsonify({'status': 'error', 'message': '服务器内部错误'}), 500


def _process_agent_report():
    data = request.get_json(silent=True) or {}

    if not data:
        return jsonify({'status': 'error', 'message': '无效的JSON数据'}), 400

    # 提取关键信息
    host_identifier = data.get('host_identifier')
    asset_name = data.get('name', '')
    specifications = data.get('specifications', {})
    agent_id = data.get('agent_id')
    agent_version = data.get('agent_version', 'unknown')

    # 处理报告时间
    report_time_str = data.get('report_time')
    try:
        report_time = datetime.fromisoformat(report_time_str) if report_time_str else datetime.now()
    except ValueError:
        report_time = datetime.now()

    if not host_identifier:
        return jsonify({'status': 'error', 'message': '缺少主机唯一标识'}), 400

    success, message, asset = AssetService.process_agent_report(
        host_identifier, asset_name, specifications, agent_id, agent_version, report_time
    )

    if success:
        return jsonify({
            'status': 'success',
            'message': message,
            'asset_id': asset.id,
            'asset_number': asset.asset_number,
            'action': 'created' if asset.auto_discovered else 'updated'
        }), 200
    else:
        return jsonify({'status': 'error', 'message': message}), 400


@asset_bp.route('/api/assets/categories/tree')
@login_required
def api_categories_tree():
    categories_tree = AssetService.get_asset_categories_tree()
    return jsonify(categories_tree)


@asset_bp.route('/api/assets/statistics')
@login_required
def api_statistics():
    stats = AssetService.get_asset_statistics()
    return jsonify(stats)


@asset_bp.route('/api/assets/<int:asset_id>/maintenance', methods=['GET'])
@login_required
def api_asset_maintenance(asset_id):
    """获取资产的维护记录"""
    maintenance_logs = AssetMaintenanceLog.query.filter_by(asset_id=asset_id) \
        .order_by(AssetMaintenanceLog.maintenance_date.desc()).all()

    logs_data = []
    for log in maintenance_logs:
        logs_data.append({
            'id': log.id,
            'title': log.title,
            'maintenance_type': log.maintenance_type,
            'maintenance_type_label': log.maintenance_type_label,
            'maintenance_date': log.maintenance_date.isoformat() if log.maintenance_date else None,
            'cost': float(log.cost) if log.cost else 0,
            'status': log.status,
            'status_label': log.status_label,
            'performed_by': log.performed_by.name if log.performed_by else None
        })

    return jsonify({'maintenance_logs': logs_data})


@asset_bp.route('/api/assets/custom-fields/<int:category_id>')
@login_required
def api_category_custom_fields(category_id):
    """获取类别的自定义字段"""
    custom_fields = AssetCustomField.query.filter_by(
        category_id=category_id,
        is_active=True
    ).order_by(AssetCustomField.order_num).all()

    fields_data = []
    for field in custom_fields:
        fields_data.append({
            'id': field.id,
            'name': field.name,
            'field_type': field.field_type,
            'is_required': field.is_required,
            'options': field.get_options_list()
        })

    return jsonify({'custom_fields': fields_data})